package com.cby.operation.pay

import android.app.Activity
import android.os.Build
import android.text.TextUtils
import com.cby.operation.common.ext.showToast
import com.cby.operation.common.ui.UIStackManager
import com.cby.operation.common.util.CbyLogUtils
import com.cby.operation.common.util.FastClickUtils
import com.cby.operation.common.util.HandlerUtils
import com.cby.operation.common.util.NetworkUtils
import com.cby.operation.initialize.InitManager
import com.cby.operation.login.LoginManager
import com.cby.operation.login.data.InternalTip
import com.cby.operation.pay.bean.PayConfig
import com.cby.operation.pay.bean.PayInfo
import com.cby.operation.pay.bean.PayLimit
import com.cby.operation.pay.bean.PayResult
import com.cby.operation.pay.core.PayEngine
import com.cby.operation.pay.data.PayApiRepository
import com.cby.operation.pay.data.PayLogApiRepository
import com.cby.operation.pay.ui.PayDialogFragment
import com.cby.operation.pay.ui.PayLimitDialogFragment
import com.cby.operation.pay.ui.PayResultDialogFragment
import com.cby.operation.pay.ui.PayRetryDialogFragment
import com.cby.operation.sdk.*
import java.util.concurrent.atomic.AtomicBoolean


/**
 * @description: PayManager
 *
 * @author ChenBaoyang
 * @date 8/4/21 16:46
 */
class PayManager {


    private lateinit var activity: Activity

    private lateinit var listener: PayListener

    lateinit var engine: PayEngine

    private var payConfig: PayConfig? = null

    private val isPaying = AtomicBoolean(false)

    private object SingletonHolder {
        /**
         * 返回InitManager对象
         */
        val instance = PayManager()
    }


    companion object {
        val instance = SingletonHolder.instance

        private const val TAG = "PayManager"
    }


    /**
     * 支付
     *
     * @param activity Activity
     * @param payInfo PayInfo
     * @param listener PayListener
     */
    fun doPay(activity: Activity, payInfo: PayInfo, listener: PayListener) {

        this.activity = activity
        this.listener = listener
        if (activity == null) {
            listener.onPayResult(
                ERR_CODE_ACTIVITY_IS_NULL,
                ERR_MSG_SDK_ACTIVITY_IS_NULL,
                payInfo
            )
            return
        }
        if (!NetworkUtils.isConnected(activity)) {
            activity.showToast(ERR_MSG_NETWORK_ERROR)
            listener.onPayResult(
                ERR_CODE_NETWORK_ERROR,
                ERR_MSG_NETWORK_ERROR,
                payInfo
            )
            return
        }
        if (!InitManager.instance.isInitOK()) {
            handlePayCallBack(
                createPayResult(
                    ERR_CODE_SDK_NOT_INIT_OK,
                    ERR_MSG_SDK_NOT_INIT_OK,
                    payInfo
                )
            )
            return
        }
        if (FastClickUtils.isFastDoubleClick) {
            return
        }
        if (payInfo != null && TextUtils.isEmpty(payInfo.goodsName)) {
            handlePayCallBack(
                createPayResult(
                    ERR_CODE_PAY_GOOD_EMPTY,
                    ERR_MSG_PAY_GOOD_EMPTY, payInfo
                )
            )
            return
        }
        if (payInfo != null && payInfo.goodsName?.length!! > 16) {
            handlePayCallBack(
                createPayResult(
                    ERR_CODE_PAY_GOOD_LENGTH_OVER,
                    ERR_MSG_PAY_GOOD_LENGTH_OVER, payInfo
                )
            )
            return
        }
        if (payInfo != null && payInfo.money <= 0) {
            handlePayCallBack(
                createPayResult(
                    ERR_CODE_PAY_MONEY_NEED_OVER_ZERO,
                    ERR_MSG_PAY_MONEY_NEED_OVER_ZERO, payInfo
                )
            )
            return
        }
        if (payInfo != null && payInfo.money > 50000) {
            handlePayCallBack(
                createPayResult(
                    ERR_CODE_PAY_MONEY_NEED_LESS_5W,
                    ERR_MSG_PAY_MONEY_NEED_LESS_5W, payInfo
                )
            )
            return
        }

        if (payInfo != null && TextUtils.isEmpty(payInfo.cpOrderId)) {
            //cp的订单号不能为空
            handlePayCallBack(
                createPayResult(
                    ERR_CODE_PAY_CP_ORDER_EMPTY,
                    ERR_MSG_PAY_CP_ORDER_EMPTY, payInfo
                )
            )
            return
        }
        if (payInfo != null && payInfo.cpOrderId!!.length > 128) {
            //cp的订单号不能为空
            handlePayCallBack(
                createPayResult(
                    ERR_CODE_PAY_CP_ORDER_LENGTH_OVER,
                    ERR_MSG_PAY_CP_ORDER_LENGTH_OVER, payInfo
                )
            )
            return
        }
        if (!LoginManager.instance.isLogin()) {
            handlePayCallBack(
                createPayResult(
                    ERR_CODE_SDK_NOT_LOGIN,
                    ERR_MSG_SDK_LOGIN_EXCEPTION, payInfo
                )
            )
            return
        }
        if (isPaying.get()) {
            //已经在支付中了，不让重复调用
            CbyLogUtils.i(TAG, "isPaying == true")
            return
        }
        isPaying.set(true)
        CbyLogUtils.i(TAG, "payinfo = $payInfo")
        engine = PayEngine(activity, payInfo)
        //先调支付配置，获取支付配置
        PayApiRepository.loadPayConfig(object : PayApiRepository.OnPayConfigCallBack {
            override fun onResponseOk(config: PayConfig?) {
                payConfig = config
                showPayDialog(payInfo, config!!)
            }

            override fun onResponseFailed(code: Int, message: String?) {
                resetPayFlag()
                if (code == CODE_PAY_MAINTENANCE ||
                    code == CODE_PAY_CLOSE
                ) {
                    //支付方式维护中
                    activity.showToast(message.toString())
                    val result = PayResult()
                    result.payInfo = payInfo
                    result.resultCode = code
                    result.message = message
                    handlePayCallBack(result)
                } else if (code == CODE_USER_ROBBED&& message != null) {
                    //code : 2003 表示用户被抢登
                    handleUserRobbed(message)
                } else {
                    val result = PayResult()
                    result.payInfo = payInfo
                    result.resultCode = code
                    result.message = message
                    handlePayCallBack(result)
                    CbyLogUtils.e(TAG, message)
                }
            }
        })
    }

    /**
     * 用户被强登，弹出弹出提示
     * @param message String
     */
    fun handleUserRobbed(message: String) {
        resetPayFlag()
        LoginManager.instance.logout(activity)
        val tip2 = InternalTip(
            tipContent = message,
            negativeBtnName = STRING_EXIT_GAME,
            negativeBtnAction = ACTION_TIP_NEGATIVE_EXIT_GAME,
            positiveBtnName = STRING_LOGIN_AGAIN,
            positiveBtnAction = ACTION_TIP_POSITIVE_LOGIN_AGAIN
        )
        HandlerUtils.runOnMainThread{
            LoginManager.instance.userBanned(activity, tip2)
        }
    }

    /**
     * 显示支付下单页面
     *
     * @param payInfo 支付信息
     * @param config  支付配置
     */
    private fun showPayDialog(payInfo: PayInfo, config: PayConfig) {
        //找不到对应的支付渠道信息， 不显示弹窗
        if (!checkPayChannels(config)) {
            activity.showToast("充值维护中，给您带来不便，敬请谅解")
            return
        }

        HandlerUtils.runOnMainThread(Runnable {
            PayDialogFragment.show(activity, payInfo, config)
        })

    }

    private fun checkPayChannels(config: PayConfig?): Boolean {
        var hasChannels = false
        if (config?.payChannels != null) {
            for (i in config!!.payChannels!!.indices) {
                val channelValue: String = config!!.payChannels!![i]
                if (TextUtils.equals(
                        channelValue,
                        VALUE_PAY_CHANNEL_WECHAT_H5
                    ) ||
                    TextUtils.equals(channelValue, VALUE_PAY_CHANNEL_ALIPAY)
                ) {
                    hasChannels = true
                }
                break
            }
        }
        return hasChannels
    }

    /**
     * 显示支付结果页面
     *
     * @param result
     */
    fun showPayResultDialog(result: PayResult) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            if (activity.isFinishing || activity.isDestroyed) {
                return
            }
        } else {
            if (activity.isFinishing) {
                return
            }
        }
        HandlerUtils.runOnMainThread {
            if (UIStackManager.instance!!.hasFragment(TAG_FRAGMENT_ANTI)) {
                val fragment : PayResultDialogFragment =
                    UIStackManager.instance!!.getFragment(TAG_FRAGMENT_PAY_RESULT) as PayResultDialogFragment
                fragment.update(payConfig, result)
                return@runOnMainThread
            }
            PayResultDialogFragment.show(activity, payConfig, result)
        }


    }

    /**
     * 显示支付限额页面
     *
     * @param payLimit
     */
    fun showPayLimitDialog(payLimit: PayLimit?, payInfo: PayInfo?) {
        HandlerUtils.runOnMainThread(Runnable {
            PayLimitDialogFragment.show(activity, payLimit, payInfo)
        })

    }

    /**
     * 支付结果处理
     *
     * @param result PayResult
     */
    fun handlePayCallBack(result: PayResult) {
        CbyLogUtils.flog(
            "result.resultCode = ${result.resultCode.toString()} result.message = ${result.message}"
        )
        resetPayFlag()
        listener.onPayResult(result.resultCode, result.message, result.payInfo)
    }

    /**
     * 创建支付结果
     *
     * @param code Int
     * @param message String
     * @param payInfo PayInfo
     * @return PayResult
     */
    private fun createPayResult(
        code: Int,
        message: String,
        payInfo: PayInfo
    ): PayResult {
        val result = PayResult()
        result.payInfo = payInfo
        result.resultCode = code
        result.message = message
        return result
    }

    fun resetPayFlag() {
        isPaying.set(false)
    }

    /**
     * 执行重新查询订单
     */
    fun doRetryQueryPayOrder(payResult: PayResult?) {
        HandlerUtils.runOnMainThread {
            PayRetryDialogFragment.show(activity!!, payResult)
        }
    }

    fun getContact(): String? {
        return if (payConfig != null) {
            payConfig!!.contact
        } else ""
    }

    /**
     * 对外接口，给游戏上报，发放商品的通知
     * @param cpOrderId
     * @param money
     * @param goodsName
     */
    fun reportNotifyGoods(cpOrderId: String, money: String, goodsName: String) {
        PayLogApiRepository.notifyGoods(cpOrderId, money, goodsName)
    }

    /**
     * unity回调上报
     */
    fun unityCallBackReport(cpOrderId: String) {
        PayLogApiRepository.unityCallBackReport(cpOrderId)
    }

}